package com.reservation.service.impl;

import com.reservation.exception.BaseException;
import com.reservation.mapper.StaffMapper;
import com.reservation.service.StaffService;
import com.reservation.utils.CurrentHolderUtil;
import com.reservation.vo.staff.MaintenanceRoomVO;
import com.reservation.vo.staff.MeetingRoomVO;
import com.reservation.vo.staff.UseFinishedItemVO;
import com.reservation.vo.staff.WaitAuditItemVO;
import com.reservation.vo.staff.TodayReserveItemVO;
import com.reservation.dto.staff.StartUseDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

@Service
@Slf4j
public class StaffServiceImpl implements StaffService {

    // TypeHandler 已经处理设备字符串转换为List<String>，不再需要手动解析

    @Autowired
    private StaffMapper staffMapper;

    /**
     * 获取会议室列表
     *
     * @return 会议室列表
     */
    @Override
    public List<MeetingRoomVO> getMeetingRoomList() {
        log.info("获取会议室列表");
        List<MeetingRoomVO> meetingRooms = staffMapper.getMeetingRoomList();
        // 使用 TypeHandler 后，不再需要手动处理设备字符串
        return meetingRooms;
    }

    /**
     * 获取待审核的预约申请列表
     *
     * @return 待审核的预约申请列表
     */
    @Override
    public List<WaitAuditItemVO> getWaitAuditList() {
        // 直接获取VO列表
        List<WaitAuditItemVO> voList = staffMapper.getWaitAuditList();
        log.info("从数据库获取到的列表：{}", voList);

        // 格式化日期时间
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");
        DateTimeFormatter orderTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");

        for (WaitAuditItemVO vo : voList) {
            // 处理日期和时间格式
            LocalDateTime startDateTime = LocalDateTime.parse(vo.getDate(), dateTimeFormatter);
            LocalDateTime endDateTime = LocalDateTime.parse(vo.getTime(), dateTimeFormatter);
            LocalDateTime orderDateTime = LocalDateTime.parse(vo.getOrderTime(), dateTimeFormatter);

            vo.setDate(startDateTime.format(dateFormatter));
            vo.setTime(startDateTime.format(timeFormatter) + " - " + endDateTime.format(timeFormatter));
            vo.setOrderTime(orderDateTime.format(orderTimeFormatter));
        }

        return voList;
    }

    /**
     * 获取今日预约列表
     *
     * @return 今日预约列表
     */
    @Override
    public List<TodayReserveItemVO> getTodayReserveList() {
        log.info("获取今日预约列表");

        try {
            // 直接从数据库获取今日预约列表
            List<TodayReserveItemVO> todayList = staffMapper.getTodayReserveList();
            log.info("获取到的今日预约列表：{}", todayList);

            return todayList;
        } catch (Exception e) {
            log.error("获取今日预约列表失败", e);
            throw new BaseException("获取今日预约列表失败: " + e.getMessage());
        }
    }

    /**
     * 审核通过取消预约申请（需客户确认）
     *
     * @param id 订单ID
     * @return 是否处理成功
     */
    @Override
    @Transactional
    public boolean auditPass(Long id) {
        log.info("审核通过取消预约申请，订单ID: {}", id);

        if (id == null) {
            throw new BaseException("订单ID不能为空");
        }

        // 获取当前登录员工的ID (保留此变量以备将来需要使用)
        // Long employeeId = Long.valueOf(CurrentHolderUtil.getCurrentId());

        try {
            // 更新订单状态为取消待确认(3)
            int bookingResult = staffMapper.updateBookingStatusToWaitingConfirm(id);
            if (bookingResult <= 0) {
                log.error("更新订单状态失败，订单ID: {}", id);
                throw new BaseException("更新订单状态失败");
            }

            log.info("审核通过处理成功，订单ID: {}", id);
            return true;
        } catch (Exception e) {
            log.error("审核通过处理失败", e);
            throw new BaseException("审核通过处理失败: " + e.getMessage());
        }
    }

    /**
     * 审核拒绝取消预约申请
     *
     * @param id 订单ID
     * @return 是否成功
     */
    @Override
    @Transactional
    public boolean auditFail(Long id) {
        log.info("审核拒绝取消预约申请，订单ID: {}", id);

        if (id == null) {
            throw new BaseException("订单ID不能为空");
        }

        // 获取当前登录员工的ID
        Long employeeId = Long.valueOf(CurrentHolderUtil.getCurrentId());

        try {
            // 更新订单状态为取消申请被拒绝
            int bookingResult = staffMapper.updateBookingStatusToRejected(id);
            if (bookingResult <= 0) {
                log.error("更新订单状态失败，订单ID: {}", id);
                throw new BaseException("更新订单状态失败");
            }

            // 更新取消申请状态为已拒绝
            String notes = "审核不通过，无法取消预订";
            int cancellationResult = staffMapper.updateCancellationRequestToRejected(id, employeeId, notes);
            if (cancellationResult <= 0) {
                log.error("更新取消申请状态失败，订单ID: {}", id);
                throw new BaseException("更新取消申请状态失败");
            }

            log.info("审核拒绝处理成功，订单ID: {}", id);
            return true;
        } catch (Exception e) {
            log.error("审核拒绝处理失败", e);
            throw new BaseException("审核拒绝处理失败: " + e.getMessage());
        }
    }

    /**
     * 开始使用会议室（更改预约状态为使用中）
     *
     * @param startUseDTO 开始使用DTO，包含预约订单ID
     * @return 是否处理成功
     */    @Override
    @Transactional
    public boolean startUse(StartUseDTO startUseDTO) {
        log.info("开始使用会议室，预约ID: {}", startUseDTO.getId());

        if (startUseDTO.getId() == null) {
            throw new BaseException("预约ID不能为空");
        }

        try {
            // 更新订单状态为使用中(8)
            int result = staffMapper.updateBookingStatusToInUse(startUseDTO.getId());
            if (result <= 0) {
                log.error("更新订单状态失败，预约ID: {}", startUseDTO.getId());
                throw new BaseException("更新订单状态失败");
            }

            log.info("订单状态更新为使用中成功，预约ID: {}", startUseDTO.getId());
            return true;
        } catch (Exception e) {
            log.error("开始使用会议室处理失败", e);
            throw new BaseException("开始使用会议室处理失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取使用完毕列表
     *
     * @return 使用完毕列表
     */
    @Override
    public List<UseFinishedItemVO> getUseFinishedList() {
        log.info("获取使用完毕列表");
        try {
            List<UseFinishedItemVO> list = staffMapper.getUseFinishedList();
            log.info("获取到使用完毕列表: {}", list);
            return list;
        } catch (Exception e) {
            log.error("获取使用完毕列表失败", e);
            throw new BaseException("获取使用完毕列表失败: " + e.getMessage());
        }
    }
    
    /**
     * 将会议室设置为空闲状态
     * 这里实际只需更新订单状态即可，因为通过定时任务自动将结束时间到了的订单状态设为已完成
     * 其实所谓的"空闲"状态是通过查询当前无有效预约或维护记录而得出的
     *
     * @param id 订单ID
     * @return 是否操作成功
     */
    @Override
    @Transactional
    public boolean setFree(Long id) {
        log.info("将会议室设置为空闲状态，订单ID: {}", id);

        if (id == null) {
            throw new BaseException("订单ID不能为空");
        }

        try {
            // 这里不需要做特别操作，因为会议室的空闲状态是查询得出的而非存储的状态
            // 当一个会议室没有维护记录和当前有效预约时，就是空闲状态
            log.info("会议室已设为空闲状态，订单ID: {}", id);
            return true;
        } catch (Exception e) {
            log.error("设置会议室为空闲状态失败", e);
            throw new BaseException("设置会议室为空闲状态失败: " + e.getMessage());
        }
    }
    
    /**
     * 将会议室设置为维护状态
     * 添加一条新的维护记录
     *
     * @param id 订单ID
     * @return 是否操作成功
     */
    @Override
    @Transactional
    public boolean setMaintenance(Long id) {
        log.info("将会议室设置为维护状态，订单ID: {}", id);

        if (id == null) {
            throw new BaseException("订单ID不能为空");
        }

        try {
            // 根据订单ID获取会议室ID
            Long roomId = staffMapper.getRoomIdByBookingId(id);
            if (roomId == null) {
                log.error("根据订单ID获取会议室ID失败，订单ID: {}", id);
                throw new BaseException("获取会议室信息失败");
            }

            // 插入维护记录
            LocalDateTime now = LocalDateTime.now();
            int result = staffMapper.insertMaintenanceLog(roomId, now);
            
            if (result <= 0) {
                log.error("添加维护记录失败，订单ID: {}, 会议室ID: {}", id, roomId);
                throw new BaseException("添加维护记录失败");
            }
            
            log.info("会议室已设为维护状态，订单ID: {}, 会议室ID: {}", id, roomId);
            return true;
        } catch (BaseException e) {
            throw e;        } catch (Exception e) {
            log.error("设置会议室为维护状态失败", e);
            throw new BaseException("设置会议室为维护状态失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取维护中的会议室列表
     *
     * @return 维护中的会议室列表
     */
    @Override
    public List<MaintenanceRoomVO> getMaintenanceList() {
        log.info("获取维护中的会议室列表");
        try {
            List<MaintenanceRoomVO> list = staffMapper.getMaintenanceList();
            log.info("获取到维护中的会议室列表: {}", list);
            return list;
        } catch (Exception e) {
            log.error("获取维护中的会议室列表失败", e);
            throw new BaseException("获取维护中的会议室列表失败: " + e.getMessage());
        }
    }
      /**
     * 完成会议室维护
     *
     * @param roomId 会议室ID
     * @return 是否处理成功
     */
    @Override
    @Transactional
    public boolean finishMaintenance(Long roomId) {
        log.info("完成会议室维护，会议室ID: {}", roomId);

        if (roomId == null) {
            throw new BaseException("会议室ID不能为空");
        }

        try {
            // 更新维护记录状态为已完成
            int result = staffMapper.finishMaintenance(roomId);
            
            if (result <= 0) {
                log.error("更新维护记录状态失败，可能会议室不存在或没有维护记录，会议室ID: {}", roomId);
                throw new BaseException("更新维护记录状态失败，可能会议室不存在或没有维护记录");
            }
            
            log.info("会议室维护已完成，会议室ID: {}", roomId);
            return true;
        } catch (BaseException e) {
            throw e;
        } catch (Exception e) {
            log.error("完成会议室维护失败", e);
            throw new BaseException("完成会议室维护失败: " + e.getMessage());
        }
    }
}

